﻿using Ekton_Manage_DomainCore;
using Ekton_Manage_DomainCore.Aggregate;
using Ekton_Manage_DTO.RequestModels.User;
using Ekton_Manage_Framework.Methods;
using Ekton_Manage_Framework.Redis;
using Ekton_Manage_IBusiness;
using Ekton_Manage_InfrastructureCore.Common;
using Ekton_Manage_InfrastructureCore.Repositories;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Mail;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using MimeKit;
using MimeKit.Text;

namespace Ekton_Manage_Business
{
    class SelectMsgPushList : ISelectMsgPushList
    {
        private readonly SerializeParameter _serialize;
        private readonly IBaseRepository<msg_push, int> _baseMaterialRepository;
        private readonly IBaseRepository<user_list, int> _baseuserlistRepository;
        private readonly IBaseRepository<msg_user, int> _basemsguserRepository;
        private readonly IBaseRepository<company_email, int> _basecompanyEmailrepository;
        private readonly ApplicationDbContent _content;
        private IHttpContextAccessor _accessor;
        public SelectMsgPushList(IBaseRepository<msg_push, int> baseMaterialRepository, SerializeParameter serialize, IBaseRepository<msg_user, int> basemsguserRepository, IBaseRepository<user_list, int> baseuserlistRepository, ApplicationDbContent content, IBaseRepository<company_email, int> basecompanyEmailrepository, IHttpContextAccessor accessor)
        {
            _baseMaterialRepository = baseMaterialRepository;
            _basemsguserRepository = basemsguserRepository;
            _baseuserlistRepository = baseuserlistRepository;
            _basecompanyEmailrepository = basecompanyEmailrepository;
            _serialize = serialize;
            _content = content;
            _accessor = accessor;
        }

        /// <summary>
        /// 查询全部消息
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<Tuple<List<msg_push>, int>> SelectMsgList(QueryDataParame query)
        {
            var dicData = await _serialize.ParameConvertToDict(query.parame);
            Expression<Func<msg_push, bool>> expression = m => true;
            if (dicData.ContainsKey("title") && !string.IsNullOrEmpty(dicData["title"].ToString()))
            {
                expression = expression.ExpressionAnd(m => m.title.Contains(dicData["title"].ToString()));
            }

            if (dicData.ContainsKey("push") && !string.IsNullOrEmpty(dicData["push"].ToString()))
            {
                expression = expression.ExpressionAnd(m => Convert.ToString(m.push).Contains(dicData["push"].ToString()));
            }

            if (dicData.ContainsKey("state") && !string.IsNullOrEmpty(dicData["state"].ToString()))
            {
                expression = expression.ExpressionAnd(m => m.state == dicData["state"].ObjToInt());
            }


            return await _baseMaterialRepository.QueryPageData(query, expression);

        }

        /// <summary>
        /// 删除消息推送
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<Message> DeleteMsgList(int id)
        {
            var usermsgid = new List<int>();
            var userlist = await _basemsguserRepository.QueryTableList(m => m.msg_id == id);
            foreach (var item in userlist)
            {
                usermsgid.Add(item.id);
            }
            //删除所有关于这条消息推送的信息
            await _basemsguserRepository.DeleteArray(usermsgid);
            var list = await _baseMaterialRepository.DeleteSingleData(id);
            return new Message(list);
        }


        /// <summary>
        /// 增加消息
        /// </summary>
        /// <param name="prouderType"></param>
        /// <remarks>
        /// push_user为0代表推送全部用户，为1代表推送指定用户，需要传push_user_list数组
        /// </remarks>
        /// <returns></returns>
        public async Task<Message> PostMsgList(DtoInsertMsgPush prouderType)
        {
            #region 拿到当前登录人的信息
            string claimInfo = string.Empty;
            LoginUser loginUser = new();
            if (_accessor.HttpContext != null)
            {
                claimInfo = (_accessor.HttpContext.AuthenticateAsync().Result.Principal.Claims).FirstOrDefault(t => t.Type.Equals(ClaimTypes.NameIdentifier))?.Value;
                loginUser = JsonConvert.DeserializeObject<LoginUser>(claimInfo);
            }
            #endregion
            //系统推送
            if (prouderType.push == 0)
            {
                //立即推送
                if (prouderType.push_method == 0)
                {
                    var push_name = await _baseuserlistRepository.QuerySingleData(prouderType.id);
                    //msg_push表
                    var userInfo = await _baseMaterialRepository.InsertSingleData(new msg_push
                    {
                        title = prouderType.title,
                        incident_name = prouderType.incident_name,
                        //result = prouderType.result,
                        result = "成功",
                        state = 1,
                        //push_name = prouderType.push_name,
                        push_name = loginUser.name,
                        push = prouderType.push,
                        msg_context = prouderType.msg_context,
                        push_method = prouderType.push_method,
                        push_user = prouderType.push_user,
                        push_time = Convert.ToDateTime(prouderType.push_time.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")),
                        push_user_list = prouderType.push_user_list,
                        img_url = prouderType.img_url,
                        push_user_email = prouderType.push_user_email
                    });
                    //存放发送用户的id
                    var userId = new List<msg_user>();
                    var empty = new List<msg_user>();
                    //获取到最新添加的msg_id
                    var msg_id = _content.Set<msg_push>()
                                       .Select(x => x.id)
                                       .Max();
                    //msg_user表
                    if (prouderType.push_user == 0)
                    {
                        //推送全部用户
                        var user = await _baseuserlistRepository.QueryTableList(m => true);
                        foreach (var item in user)
                        {
                            userId.Add(new msg_user
                            {
                                user_id = item.id,
                                msg_id = msg_id,
                                look_state = 0
                            });
                        }
                        //批量添加消息推送
                        var insertMsgUser = await _basemsguserRepository.InsertManyData(userId);
                    }
                    else if (prouderType.push_user == 1)
                    {
                        //推送指定用户
                        string[] strArray = prouderType.push_user_list.Split(',');
                        var intArray = Array.ConvertAll(strArray, int.Parse);
                        for (int i = 0; i < intArray.Length; i++)
                        {
                            empty.Add(new msg_user
                            {
                                user_id = intArray[i],
                                msg_id = msg_id,
                                look_state = 0
                            });
                        }
                        var insertMsgUser = await _basemsguserRepository.InsertManyData(empty);
                        return new Message(insertMsgUser);
                    }
                }
                else if (prouderType.push_method == 1)
                {
                    //定时推送
                    //msg_push表
                    var userInfo = await _baseMaterialRepository.InsertSingleData(new msg_push
                    {
                        title = prouderType.title,
                        incident_name = prouderType.incident_name,
                        //result = prouderType.result,
                        result = "成功",
                        state = 0,
                        //push_name = prouderType.push_name,
                        push_name = loginUser.name,
                        push = prouderType.push,
                        msg_context = prouderType.msg_context,
                        push_method = prouderType.push_method,
                        push_user = prouderType.push_user,
                        push_time = Convert.ToDateTime(prouderType.push_time.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")),
                        push_user_list = prouderType.push_user_list,
                        push_user_email = prouderType.push_user_email,
                        img_url = prouderType.img_url
                    });
                }
            }
            //邮箱通知
            else if (prouderType.push == 1)
            {
                //存放用户的id
                // var userId = new List<user_msg>();
                var userInfo = await _baseuserlistRepository.QueryTableList(m => true);
                //msg_push表

                //立即推送
                if (prouderType.push_method == 0)
                {
                    await _baseMaterialRepository.InsertSingleData(new msg_push
                    {
                        title = prouderType.title,
                        incident_name = prouderType.incident_name,
                        //result = prouderType.result,
                        result = "成功",
                        state = 1,
                        //push_name = prouderType.push_name,
                        push_name = loginUser.name,
                        push = prouderType.push,
                        msg_context = prouderType.msg_context,
                        push_method = prouderType.push_method,
                        push_user = prouderType.push_user,
                        push_time = Convert.ToDateTime(prouderType.push_time.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")),
                        push_user_list = prouderType.push_user_list,
                        img_url = prouderType.img_url,
                        push_user_email = prouderType.push_user_email
                    });
                    if (prouderType.push_user == 0)
                    {
                        var companyEmail = await _basecompanyEmailrepository.QuerySingleData(m => m.platform_id == 30);
                        if (companyEmail == null) return new Message("平台id有误！", false, 202);
                        Task.Run(async () =>
                        {
                            string address = "";//收件人
                            foreach (var item in userInfo)
                            {
                                address += item.email + ",";
                            }
                            string host = "smtp.qq.com";//qq邮箱
                            int port = 465;//25 465 587
                            //发件人的邮箱
                            string from = companyEmail.email;
                            string to = address;
                            //发件人邮箱@符前面的部分
                            var temp = companyEmail.email.Split("@")[0];
                            string userName = temp;//用户登录名
                            string password = companyEmail.author_code;//授权码

                            var message = new MimeMessage();
                            message.From.Add(new MailboxAddress(from));
                            //message.To.AddRange(new MailboxAddress[] { new MailboxAddress(to) });
                            message.Subject = prouderType.title;
                            var entity = new TextPart(TextFormat.Html)
                            {
                                Text = prouderType.msg_context
                            };
                            message.Body = entity;
                            MailKit.Net.Smtp.SmtpClient client = new MailKit.Net.Smtp.SmtpClient();
                            client.Connect(host, port, port == 465);//465端口是ssl端口
                            client.Authenticate(userName, password);
                            string[] email = address.Split(',');
                            foreach (string name in email)
                            {
                                if (name is null) { };
                                if (name != string.Empty)
                                {
                                    //每次发邮件前清空收件人
                                    message.To.Clear();
                                    address = name;
                                    message.To.AddRange(new MailboxAddress[] { new MailboxAddress(name) });
                                    client.Send(message);
                                }
                            }
                            client.Disconnect(true);

                            return new Message("发送邮件成功");
                        });

                        Console.WriteLine("发送邮件成功");
                        return new Message(true);
                    }
                    //指定用户推送
                    else if (prouderType.push_user == 1)
                    {
                        Console.WriteLine("指定用户推送come in" + new string('-', 100) + "指定用户推送");
                        //查询发送邮件的发件人邮箱
                        var companyEmail = await _basecompanyEmailrepository.QuerySingleData(m => m.platform_id == 26);
                        if (companyEmail == null) return new Message("平台id有误！", false, 202);
                        Task.Run(() =>
                        {
                            Console.WriteLine(new string('-', 100));
                            Console.WriteLine("指定用户推送come" + new string('-', 100) + "指定用户推送");
                            var empty = new List<msg_user>();
                            MailMessage mailMessage = new MailMessage();
                            //推送指定用户
                            string address = prouderType.push_user_email;
                            string host = "smtp.qq.com";//qq邮箱
                            int port = 465;//25 465 587
                            //发件人的邮箱
                            string from = companyEmail.email;
                            string to = address;
                            //发件人邮箱@符前面的部分
                            var temp = companyEmail.email.Split("@")[0];
                            string userName = temp;//用户登录名
                            string password = companyEmail.author_code;//授权码

                            var message = new MimeMessage();
                            message.From.Add(new MailboxAddress(from));
                            //message.To.AddRange(new MailboxAddress[] { new MailboxAddress(to) });
                            message.Subject = prouderType.title;
                            var entity = new TextPart(TextFormat.Html)
                            {
                                Text = prouderType.msg_context
                            };
                            message.Body = entity;
                            MailKit.Net.Smtp.SmtpClient client = new MailKit.Net.Smtp.SmtpClient();
                            client.Connect(host, port, port == 465);//465端口是ssl端口
                            client.Authenticate(userName, password);
                            string[] email = address.Split(',');
                            foreach (string name in email)
                            {
                                if (name is null) { };
                                if (name != string.Empty)
                                {
                                    //每次发邮件前清空收件人
                                    message.To.Clear();
                                    address = name;
                                    message.To.AddRange(new MailboxAddress[] { new MailboxAddress(name) });
                                    client.Send(message);
                                }
                            }
                            Console.WriteLine(new string('-', 100));
                            Console.WriteLine("发送邮件成功");
                            Console.WriteLine(new string('-', 100));
                            client.Disconnect(true);
                            return new Message("发送邮件成功");
                        });
                        return new Message(true);
                    }
                }
                else if (prouderType.push_method == 1)
                {
                    //定时推送
                    if (prouderType.push_user == 0)//全部用户
                    {
                        await _baseMaterialRepository.InsertSingleData(new msg_push
                        {
                            title = prouderType.title,
                            incident_name = prouderType.incident_name,
                            //result = prouderType.result,
                            result = "成功",
                            state = 0,//未推送=>定时推送
                            //push_name = prouderType.push_name,
                            push_name = loginUser.name,
                            push = prouderType.push,
                            msg_context = prouderType.msg_context,
                            push_method = prouderType.push_method,
                            push_user = prouderType.push_user,
                            push_time = Convert.ToDateTime(prouderType.push_time.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")),
                            push_user_list = prouderType.push_user_list,
                            push_user_email = prouderType.push_user_email,
                            img_url = prouderType.img_url
                        });
                        //存放发送用户的id
                        var userId = new List<msg_user>();
                        var empty = new List<msg_user>();
                        //获取到最新添加的msg_id
                        var msg_id = _content.Set<msg_push>()
                                           .Select(x => x.id)
                                           .Max();
                        //推送全部用户
                        var user = await _baseuserlistRepository.QueryTableList(m => true);
                        foreach (var item in user)
                        {
                            userId.Add(new msg_user
                            {
                                user_id = item.id,
                                msg_id = msg_id,
                                look_state = 0
                            });
                        }
                        //批量添加消息推送
                        var insertMsgUser = await _basemsguserRepository.InsertManyData(userId);
                    }
                    else if (prouderType.push_user == 1)//指定用户
                    {
                        await _baseMaterialRepository.InsertSingleData(new msg_push
                        {
                            title = prouderType.title,
                            incident_name = prouderType.incident_name,
                            //result = prouderType.result,
                            result = "成功",
                            state = 0,//未推送
                            //push_name = prouderType.push_name,
                            push_name = loginUser.name,
                            push = prouderType.push,
                            msg_context = prouderType.msg_context,
                            push_method = prouderType.push_method,
                            push_user = prouderType.push_user,
                            push_time = Convert.ToDateTime(prouderType.push_time.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")),
                            push_user_list = prouderType.push_user_list,
                            img_url = prouderType.img_url,
                            push_user_email = prouderType.push_user_email
                        });
                        //return new Message(true);
                    }
                }
            }
            return new Message(200);
        }

        /// <summary>
        /// 定时推送消息 点击推送后立即推送
        /// </summary>
        /// <remarks>
        /// 传消息推送的id
        /// </remarks>
        /// <returns></returns>
        public async Task<Message> PutMsgListByNow(int id)
        {
            var prouderType = await _baseMaterialRepository.QuerySingleData(m => m.id == id);
            if (prouderType.push == 0)//系统推送
            {
                if (prouderType.state == 0)
                {
                    //该消息没有推送的情况
                    var push_name = await _baseuserlistRepository.QuerySingleData(prouderType.id);
                    //存放发送用户的id
                    var userId = new List<msg_user>();
                    var empty = new List<msg_user>();
                    //msg_user表
                    if (prouderType.push_user == 0)
                    {
                        //推送全部用户
                        var user = await _baseuserlistRepository.QueryTableList(m => true);
                        foreach (var item in user)
                        {
                            userId.Add(new msg_user
                            {
                                user_id = item.id,
                                msg_id = id,
                                look_state = 0
                            });
                        }
                        //批量添加消息推送
                        var insertMsgUser = await _basemsguserRepository.InsertManyData(userId);
                    }
                    else if (prouderType.push_user == 1)
                    {
                        //推送指定用户
                        string[] strArray = prouderType.push_user_list.Split(',');
                        var intArray = Array.ConvertAll(strArray, int.Parse);
                        for (int i = 0; i < intArray.Length; i++)
                        {
                            empty.Add(new msg_user
                            {
                                user_id = intArray[i],
                                msg_id = id,
                                look_state = 0
                            });
                        }
                        var insertMsgUser = await _basemsguserRepository.InsertManyData(empty);
                    }
                    prouderType.state = 1;
                    await _baseMaterialRepository.UpdateSingleData(prouderType);
                    return new Message(200);
                }
                else if (prouderType.state == 1)
                {
                    //该消息已经推送的情况
                    return new Message(false, 202);
                }
            }
            else if (prouderType.push == 1)//邮箱推送
            {
                if (prouderType.push_user == 0)//推送给全部用户
                {
                    var companyEmail = await _basecompanyEmailrepository.QuerySingleData(m => m.platform_id == 30);
                    if (companyEmail == null) return new Message(false, 202);
                    //查询全部用户    
                    var userInfo = await _baseuserlistRepository.QueryTableList(m => true);
                    string address = "";//收件人
                    foreach (var userItem in userInfo)
                    {
                        address += userItem.email + ",";
                    }
                    Task.Run(() =>
                    {
                        string host = "smtp.qq.com";//qq邮箱
                        int port = 465;//25 465 587
                                       //发件人的邮箱
                        string from = companyEmail.email;
                        string to = address;
                        //发件人邮箱@符前面的部分
                        var temp = companyEmail.email.Split("@")[0];
                        string userName = temp;//用户登录名
                        string password = companyEmail.author_code;//授权码

                        var message = new MimeMessage();
                        message.From.Add(new MailboxAddress(from));
                        //message.To.AddRange(new MailboxAddress[] { new MailboxAddress(to) });
                        message.Subject = prouderType.title;
                        var entity = new TextPart(TextFormat.Html)
                        {
                            Text = prouderType.msg_context
                        };
                        message.Body = entity;
                        MailKit.Net.Smtp.SmtpClient client = new MailKit.Net.Smtp.SmtpClient();
                        client.Connect(host, port, port == 465);//465端口是ssl端口
                        client.Authenticate(userName, password);
                        string[] email = address.Split(',');
                        foreach (string name in email)
                        {
                            if (name is null) { };
                            if (name != string.Empty)
                            {
                                //每次发邮件前清空收件人
                                message.To.Clear();
                                address = name;
                                message.To.AddRange(new MailboxAddress[] { new MailboxAddress(name) });
                                client.Send(message);
                            }
                        }
                        client.Disconnect(true);
                        Console.WriteLine("发送邮件成功");
                    });
                }
                else if (prouderType.push_user == 1)//推送给指定用户
                {
                    //查询发送邮件的发件人邮箱
                    var companyEmail = await _basecompanyEmailrepository.QuerySingleData(m => m.platform_id == 30);
                    if (companyEmail == null) return new Message(false, 202);
                    Task.Run(() =>
                    {
                        string address = prouderType.push_user_email;
                        string host = "smtp.qq.com";//qq邮箱
                        int port = 465;//25 465 587
                                       //发件人的邮箱
                        string from = companyEmail.email;
                        string to = address;
                        //发件人邮箱@符前面的部分
                        var temp = companyEmail.email.Split("@")[0];
                        string userName = temp;//用户登录名
                        string password = companyEmail.author_code;//授权码

                        var message = new MimeMessage();
                        message.From.Add(new MailboxAddress(from));
                        //message.To.AddRange(new MailboxAddress[] { new MailboxAddress(to) });
                        message.Subject = prouderType.title;
                        var entity = new TextPart(TextFormat.Html)
                        {
                            Text = prouderType.msg_context
                        };
                        message.Body = entity;
                        MailKit.Net.Smtp.SmtpClient client = new MailKit.Net.Smtp.SmtpClient();
                        client.Connect(host, port, port == 465);//465端口是ssl端口
                        client.Authenticate(userName, password);
                        string[] email = address.Split(',');
                        foreach (string name in email)
                        {
                            if (name is null) { };
                            if (name != string.Empty)
                            {
                                //每次发邮件前清空收件人
                                message.To.Clear();
                                address = name;
                                message.To.AddRange(new MailboxAddress[] { new MailboxAddress(name) });
                                client.Send(message);
                            }
                        }
                        client.Disconnect(true);
                        Console.WriteLine("发送邮件成功");
                    });
                }
                return new Message(200);
            }
            return null;
        }

        /// <summary>
        /// 修改消息
        /// </summary>
        /// <param name="prouderTypeId"></param>
        /// <returns></returns>
        public async Task<Message> PutMsgList(DtoInsertMsgPush prouderTypeId)
        {
            var companys = await _baseMaterialRepository.QuerySingleData(prouderTypeId.id);
            if (companys == null) return new Message(false, 202);
            companys.title = prouderTypeId.title;
            companys.incident_name = prouderTypeId.incident_name;
            companys.msg_context = prouderTypeId.msg_context;
            companys.img_url = prouderTypeId.img_url;
            var result = await _baseMaterialRepository.UpdateSingleData(companys);
            return new Message(result.Item1);
        }
    }
}
